﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;
using System.Text.RegularExpressions;

namespace ServerConsole
{
    public class Finder
    {
        /// <summary>
        /// Делегат для возвращения результатов поиска
        /// </summary>
        /// <param name="findData">Данные</param>
        /// <param name="isCompleted">Флаг окончания поиска. если true, данные = ""</param>
        public delegate void ResultEventHandler(string findData, bool isCompleted);

        string fileName = "";
        string baseDirectory;
        SearchOption searchOption = SearchOption.TopDirectoryOnly;
        ResultEventHandler resultCallback;
        bool isStoped = false;
        Thread finderThread;

        public Finder()
        {
            finderThread = new Thread(doAsyncFind);
        }

        ~Finder()
        {
            StopAsyncFind();
            if (finderThread.IsAlive)
            {
                finderThread.Abort();
            }
        }

        /// <summary>
        /// Запуск асинхронного поиска
        /// </summary>
        /// <param name="FileName">Маска поиска. Пример: "*.txt" или "*.*"</param>
        /// <param name="InnerFolders">Включить в поиск подкаталоги</param>
        /// <param name="ResultCallback">Функция для возврата результата поиска</param>
        public void BeginFind(string fileName, string baseDirectory, SearchOption searchOption, ResultEventHandler resultCallback)
        {
            if (finderThread.IsAlive)
                throw new Exception("Поиск уже производится");

            // Заполнение полей для поиска
            isStoped = false;
            this.resultCallback = resultCallback;
            this.searchOption = searchOption;
            this.fileName = fileName;
            this.baseDirectory = baseDirectory;

            // Создание нового потока, в котором будет выполняется метод doAsyncFind()
            finderThread.Start();
        }

        /// <summary>
        /// Функция поиска в *.txt файлах
        /// </summary>
        private void doAsyncFind()
        {
            //try
            //{

            //Создается регулярное выраже с "фильтром" поиска
            Regex regex = new Regex(fileName);

            //Полуаем все txt файлы в каталоге
            string[] txtFiles = Directory.GetFiles(baseDirectory, "*.txt", searchOption);

            //Открываем каждый найденный файл и ищем в них запрашевоемый файл
            foreach (string txtFile in txtFiles)
            {
                if (isStoped)
                    break;
                StreamReader sReader = File.OpenText(txtFile);
                while (!sReader.EndOfStream || !isStoped)
                {
                    string line = sReader.ReadLine();
                    if (line == null)
                        break;

                    //Если строка удовлетворяет запросу, возвращаем результат
                    if (regex.IsMatch(line))
                        resultCallback.Invoke(line, false);
                }
                sReader.Close();
            }

            // Возвращаем результат окончания поиска
            resultCallback.Invoke("", true);
            //}
            //catch (System.Exception ex)
            //{
            //}
        }

        /// <summary>
        /// Остановить поиск
        /// </summary>
        public void StopAsyncFind()
        {
            isStoped = true;
        }
    }
}
